Satellite Image Data


Analysis using numpy


Data Source: Satellite Image from WIFIRE Project

WIFIRE is an integrated system for wildfire analysis, with specific regard to changing urban dynamics and climate. The system integrates networked observations such as heterogeneous satellite data and real-time remote sensor data, with computational techniques in signal processing, visualization, modeling, and data assimilation to provide a scalable method to monitor such phenomena as weather patterns that can help predict a wildfire's rate of spread. You can read more about WIFIRE at: https://wifire.ucsd.edu/

In this example, we will analyze a sample satellite image dataset from WIFIRE using the numpy Library.

Loading the libraries we need: numpy, scipy, matplotlib

In [1]:
%matplotlib inline
import numpy as np
from scipy import misc
import matplotlib.pyplot as plt

Creating a numpy array from an image file:


Lets choose a WIFIRE satellite image file as an ndarray and display its type.

In [4]:
!pip install scikit-image
Collecting scikit-image
  Downloading https://files.pythonhosted.org/packages/ab/e8/8c0c9d26ff80dfdf51c209c8c823269adaea1d26d52c43216685bfb590a4/scikit_image-0.14.2-cp36-cp36m-macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl (28.9MB)
    100% |████████████████████████████████| 28.9MB 587kB/s ta 0:00:01    61% |███████████████████▋            | 17.7MB 703kB/s eta 0:00:16    97% |███████████████████████████████ | 28.0MB 716kB/s eta 0:00:02
Collecting PyWavelets>=0.4.0 (from scikit-image)
  Downloading https://files.pythonhosted.org/packages/03/9b/6623e4197d459529602e02e52a4a1e277b9113c562bcfaf8b64b2c38408c/PyWavelets-1.0.1-cp36-cp36m-macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl (4.9MB)
    100% |████████████████████████████████| 4.9MB 567kB/s ta 0:00:01
Requirement already satisfied: pillow>=4.3.0 in /Users/sherlock/Documents/machine-learning/python-venvs/data-sci/lib/python3.6/site-packages (from scikit-image) (5.4.1)
Requirement already satisfied: matplotlib>=2.0.0 in /Users/sherlock/Documents/machine-learning/python-venvs/data-sci/lib/python3.6/site-packages (from scikit-image) (3.0.2)
Collecting networkx>=1.8 (from scikit-image)
  Downloading https://files.pythonhosted.org/packages/f3/f4/7e20ef40b118478191cec0b58c3192f822cace858c19505c7670961b76b2/networkx-2.2.zip (1.7MB)
    100% |████████████████████████████████| 1.7MB 786kB/s ta 0:00:01    19% |██████▍                         | 337kB 543kB/s eta 0:00:03
Collecting dask[array]>=1.0.0 (from scikit-image)
  Downloading https://files.pythonhosted.org/packages/7c/2b/cf9e5477bec3bd3b4687719876ea38e9d8c9dc9d3526365c74e836e6a650/dask-1.1.1-py2.py3-none-any.whl (701kB)
    100% |████████████████████████████████| 706kB 1.2MB/s ta 0:00:01
Requirement already satisfied: scipy>=0.17.0 in /Users/sherlock/Documents/machine-learning/python-venvs/data-sci/lib/python3.6/site-packages (from scikit-image) (1.2.0)
Requirement already satisfied: six>=1.10.0 in /Users/sherlock/Documents/machine-learning/python-venvs/data-sci/lib/python3.6/site-packages (from scikit-image) (1.12.0)
Collecting cloudpickle>=0.2.1 (from scikit-image)
  Downloading https://files.pythonhosted.org/packages/47/d5/efa7cacef5d3bdcd71d7053a698fb9b64a20fff5cb3c592efefa53ea5578/cloudpickle-0.8.0-py2.py3-none-any.whl
Requirement already satisfied: numpy>=1.9.1 in /Users/sherlock/Documents/machine-learning/python-venvs/data-sci/lib/python3.6/site-packages (from PyWavelets>=0.4.0->scikit-image) (1.16.1)
Requirement already satisfied: cycler>=0.10 in /Users/sherlock/Documents/machine-learning/python-venvs/data-sci/lib/python3.6/site-packages (from matplotlib>=2.0.0->scikit-image) (0.10.0)
Requirement already satisfied: pyparsing!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.1 in /Users/sherlock/Documents/machine-learning/python-venvs/data-sci/lib/python3.6/site-packages (from matplotlib>=2.0.0->scikit-image) (2.3.1)
Requirement already satisfied: python-dateutil>=2.1 in /Users/sherlock/Documents/machine-learning/python-venvs/data-sci/lib/python3.6/site-packages (from matplotlib>=2.0.0->scikit-image) (2.8.0)
Requirement already satisfied: kiwisolver>=1.0.1 in /Users/sherlock/Documents/machine-learning/python-venvs/data-sci/lib/python3.6/site-packages (from matplotlib>=2.0.0->scikit-image) (1.0.1)
Requirement already satisfied: decorator>=4.3.0 in /Users/sherlock/Documents/machine-learning/python-venvs/data-sci/lib/python3.6/site-packages (from networkx>=1.8->scikit-image) (4.3.2)
Collecting toolz>=0.7.3; extra == "array" (from dask[array]>=1.0.0->scikit-image)
  Downloading https://files.pythonhosted.org/packages/14/d0/a73c15bbeda3d2e7b381a36afb0d9cd770a9f4adc5d1532691013ba881db/toolz-0.9.0.tar.gz (45kB)
    100% |████████████████████████████████| 51kB 5.1MB/s ta 0:00:01
Requirement already satisfied: setuptools in /Users/sherlock/Documents/machine-learning/python-venvs/data-sci/lib/python3.6/site-packages (from kiwisolver>=1.0.1->matplotlib>=2.0.0->scikit-image) (40.8.0)
Building wheels for collected packages: networkx, toolz
  Building wheel for networkx (setup.py) ... done
  Stored in directory: /Users/sherlock/Library/Caches/pip/wheels/68/f8/29/b53346a112a07d30a5a84d53f19aeadaa1a474897c0423af91
  Building wheel for toolz (setup.py) ... done
  Stored in directory: /Users/sherlock/Library/Caches/pip/wheels/f4/0c/f6/ce6b2d1aa459ee97cc3c0f82236302bd62d89c86c700219463
Successfully built networkx toolz
Installing collected packages: PyWavelets, networkx, toolz, dask, cloudpickle, scikit-image
Successfully installed PyWavelets-1.0.1 cloudpickle-0.8.0 dask-1.1.1 networkx-2.2 scikit-image-0.14.2 toolz-0.9.0
You are using pip version 19.0.1, however version 19.0.2 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
In [5]:
from skimage import data

photo_data = misc.imread('./wifire/sd-3layers.jpg')

type(photo_data)
/Users/sherlock/Documents/machine-learning/python-venvs/data-sci/lib/python3.6/site-packages/ipykernel_launcher.py:3: DeprecationWarning: `imread` is deprecated!
`imread` is deprecated in SciPy 1.0.0, and will be removed in 1.2.0.
Use ``imageio.imread`` instead.
  This is separate from the ipykernel package so we can avoid doing imports until
Out[5]:
numpy.ndarray

Let's see what is in this image.

In [6]:
plt.figure(figsize=(15,15))
plt.imshow(photo_data)
Out[6]:
<matplotlib.image.AxesImage at 0x12495cc18>
In [7]:
photo_data.shape

#print(photo_data)
Out[7]:
(3725, 4797, 3)

The shape of the ndarray show that it is a three layered matrix. The first two numbers here are length and width, and the third number (i.e. 3) is for three layers: Red, Green and Blue.

RGB Color Mapping in the Photo:


  • RED pixel indicates Altitude

  • BLUE pixel indicates Aspect

  • GREEN pixel indicates Slope

    </ul>
    The higher values denote higher altitude, aspect and slope.

In [8]:
photo_data.size
Out[8]:
53606475
In [9]:
photo_data.min(), photo_data.max()
Out[9]:
(0, 255)
In [10]:
photo_data.mean()
Out[10]:
75.8299354508947


Pixel on the 150th Row and 250th Column

In [11]:
photo_data[150, 250]
Out[11]:
array([ 17,  35, 255], dtype=uint8)
In [12]:
photo_data[150, 250, 1]
Out[12]:
35


Set a Pixel to All Zeros


We can set all three layer in a pixel as once by assigning zero globally to that (row,column) pairing. However, setting one pixel to zero is not noticeable.

In [13]:
#photo_data = misc.imread('./wifire/sd-3layers.jpg')
photo_data[150, 250] = 0
plt.figure(figsize=(10,10))
plt.imshow(photo_data)
Out[13]:
<matplotlib.image.AxesImage at 0x12e7d2390>


Changing colors in a Range


We can also use a range to change the pixel values. As an example, let's set the green layer for rows 200 t0 800 to full intensity.

In [14]:
photo_data = misc.imread('./wifire/sd-3layers.jpg')

photo_data[200:800, : ,1] = 255
plt.figure(figsize=(10,10))
plt.imshow(photo_data)
/Users/sherlock/Documents/machine-learning/python-venvs/data-sci/lib/python3.6/site-packages/ipykernel_launcher.py:1: DeprecationWarning: `imread` is deprecated!
`imread` is deprecated in SciPy 1.0.0, and will be removed in 1.2.0.
Use ``imageio.imread`` instead.
  """Entry point for launching an IPython kernel.
Out[14]:
<matplotlib.image.AxesImage at 0x128016be0>
In [15]:
photo_data = misc.imread('./wifire/sd-3layers.jpg')

photo_data[200:800, :] = 255
plt.figure(figsize=(10,10))
plt.imshow(photo_data)
/Users/sherlock/Documents/machine-learning/python-venvs/data-sci/lib/python3.6/site-packages/ipykernel_launcher.py:1: DeprecationWarning: `imread` is deprecated!
`imread` is deprecated in SciPy 1.0.0, and will be removed in 1.2.0.
Use ``imageio.imread`` instead.
  """Entry point for launching an IPython kernel.
Out[15]:
<matplotlib.image.AxesImage at 0x128072cc0>
In [16]:
photo_data = misc.imread('./wifire/sd-3layers.jpg')

photo_data[200:800, :] = 0
plt.figure(figsize=(10,10))
plt.imshow(photo_data)
/Users/sherlock/Documents/machine-learning/python-venvs/data-sci/lib/python3.6/site-packages/ipykernel_launcher.py:1: DeprecationWarning: `imread` is deprecated!
`imread` is deprecated in SciPy 1.0.0, and will be removed in 1.2.0.
Use ``imageio.imread`` instead.
  """Entry point for launching an IPython kernel.
Out[16]:
<matplotlib.image.AxesImage at 0x1280cbe10>


Pick all Pixels with Low Values

In [17]:
photo_data = misc.imread('./wifire/sd-3layers.jpg')
print("Shape of photo_data:", photo_data.shape)
low_value_filter = photo_data < 200
print("Shape of low_value_filter:", low_value_filter.shape)
/Users/sherlock/Documents/machine-learning/python-venvs/data-sci/lib/python3.6/site-packages/ipykernel_launcher.py:1: DeprecationWarning: `imread` is deprecated!
`imread` is deprecated in SciPy 1.0.0, and will be removed in 1.2.0.
Use ``imageio.imread`` instead.
  """Entry point for launching an IPython kernel.
Shape of photo_data: (3725, 4797, 3)
Shape of low_value_filter: (3725, 4797, 3)

Filtering Out Low Values


Whenever the low_value_filter is True, set value to 0.

In [18]:
#import random
plt.figure(figsize=(10,10))
plt.imshow(photo_data)
photo_data[low_value_filter] = 0
plt.figure(figsize=(10,10))
plt.imshow(photo_data)
Out[18]:
<matplotlib.image.AxesImage at 0x12c6bada0>

More Row and Column Operations


You can design complex patters by making cols a function of rows or vice-versa. Here we try a linear relationship between rows and columns.

In [19]:
rows_range = np.arange(len(photo_data))
cols_range = rows_range
print(type(rows_range))
<class 'numpy.ndarray'>
In [20]:
photo_data[rows_range, cols_range] = 255
In [21]:
plt.figure(figsize=(15,15))
plt.imshow(photo_data)
Out[21]:
<matplotlib.image.AxesImage at 0x12c672080>


Masking Images


Now let us try something even cooler...a mask that is in shape of a circular disc.

In [22]:
total_rows, total_cols, total_layers = photo_data.shape
#print("photo_data = ", photo_data.shape)

X, Y = np.ogrid[:total_rows, :total_cols]
#print("X = ", X.shape, " and Y = ", Y.shape)
In [23]:
center_row, center_col = total_rows / 2, total_cols / 2
#print("center_row = ", center_row, "AND center_col = ", center_col)
#print(X - center_row)
#print(Y - center_col)
dist_from_center = (X - center_row)**2 + (Y - center_col)**2
#print(dist_from_center)
radius = (total_rows / 2)**2
#print("Radius = ", radius)
circular_mask = (dist_from_center > radius)
#print(circular_mask)
print(circular_mask[1500:1700,2000:2200])
[[False False False ... False False False]
 [False False False ... False False False]
 [False False False ... False False False]
 ...
 [False False False ... False False False]
 [False False False ... False False False]
 [False False False ... False False False]]
In [24]:
photo_data = misc.imread('./wifire/sd-3layers.jpg')
photo_data[circular_mask] = 0
plt.figure(figsize=(15,15))
plt.imshow(photo_data)
/Users/sherlock/Documents/machine-learning/python-venvs/data-sci/lib/python3.6/site-packages/ipykernel_launcher.py:1: DeprecationWarning: `imread` is deprecated!
`imread` is deprecated in SciPy 1.0.0, and will be removed in 1.2.0.
Use ``imageio.imread`` instead.
  """Entry point for launching an IPython kernel.
Out[24]:
<matplotlib.image.AxesImage at 0x14bf1b4e0>

Further Masking


You can further improve the mask, for example just get upper half disc.

In [25]:
X, Y = np.ogrid[:total_rows, :total_cols]
half_upper = X < center_row # this line generates a mask for all rows above the center

half_upper_mask = np.logical_and(half_upper, circular_mask)
In [26]:
photo_data = misc.imread('./wifire/sd-3layers.jpg')
photo_data[half_upper_mask] = 255
#photo_data[half_upper_mask] = random.randint(200,255)
plt.figure(figsize=(15,15))
plt.imshow(photo_data)
/Users/sherlock/Documents/machine-learning/python-venvs/data-sci/lib/python3.6/site-packages/ipykernel_launcher.py:1: DeprecationWarning: `imread` is deprecated!
`imread` is deprecated in SciPy 1.0.0, and will be removed in 1.2.0.
Use ``imageio.imread`` instead.
  """Entry point for launching an IPython kernel.
Out[26]:
<matplotlib.image.AxesImage at 0x11a537438>


Further Processing of our Satellite Imagery

Processing of RED Pixels

Remember that red pixels tell us about the height. Let us try to highlight all the high altitude areas. We will do this by detecting high intensity RED Pixels and muting down other areas.

In [27]:
photo_data = misc.imread('./wifire/sd-3layers.jpg')
red_mask   = photo_data[:, : ,0] < 150

photo_data[red_mask] = 0
plt.figure(figsize=(15,15))
plt.imshow(photo_data)
/Users/sherlock/Documents/machine-learning/python-venvs/data-sci/lib/python3.6/site-packages/ipykernel_launcher.py:1: DeprecationWarning: `imread` is deprecated!
`imread` is deprecated in SciPy 1.0.0, and will be removed in 1.2.0.
Use ``imageio.imread`` instead.
  """Entry point for launching an IPython kernel.
Out[27]:
<matplotlib.image.AxesImage at 0x11a5927f0>


Detecting Highl-GREEN Pixels

In [28]:
photo_data = misc.imread('./wifire/sd-3layers.jpg')
green_mask = photo_data[:, : ,1] < 150

photo_data[green_mask] = 0
plt.figure(figsize=(15,15))
plt.imshow(photo_data)
/Users/sherlock/Documents/machine-learning/python-venvs/data-sci/lib/python3.6/site-packages/ipykernel_launcher.py:1: DeprecationWarning: `imread` is deprecated!
`imread` is deprecated in SciPy 1.0.0, and will be removed in 1.2.0.
Use ``imageio.imread`` instead.
  """Entry point for launching an IPython kernel.
Out[28]:
<matplotlib.image.AxesImage at 0x11a5ee940>


Detecting Highly-BLUE Pixels

In [29]:
photo_data = misc.imread('./wifire/sd-3layers.jpg')
blue_mask  = photo_data[:, : ,2] < 150

photo_data[blue_mask] = 0
plt.figure(figsize=(15,15))
plt.imshow(photo_data)
/Users/sherlock/Documents/machine-learning/python-venvs/data-sci/lib/python3.6/site-packages/ipykernel_launcher.py:1: DeprecationWarning: `imread` is deprecated!
`imread` is deprecated in SciPy 1.0.0, and will be removed in 1.2.0.
Use ``imageio.imread`` instead.
  """Entry point for launching an IPython kernel.
Out[29]:
<matplotlib.image.AxesImage at 0x11cad0a90>


Composite mask that takes thresholds on all three layers: RED, GREEN, BLUE

In [30]:
photo_data = misc.imread('./wifire/sd-3layers.jpg')

red_mask   = photo_data[:, : ,0] < 150
green_mask = photo_data[:, : ,1] > 100
blue_mask  = photo_data[:, : ,2] < 100

final_mask = np.logical_and(red_mask, green_mask, blue_mask)
photo_data[final_mask] = 0
plt.figure(figsize=(15,15))
plt.imshow(photo_data)
/Users/sherlock/Documents/machine-learning/python-venvs/data-sci/lib/python3.6/site-packages/ipykernel_launcher.py:1: DeprecationWarning: `imread` is deprecated!
`imread` is deprecated in SciPy 1.0.0, and will be removed in 1.2.0.
Use ``imageio.imread`` instead.
  """Entry point for launching an IPython kernel.
Out[30]:
<matplotlib.image.AxesImage at 0x11a4e92e8>
In [ ]: